PICの応用回路(2)  ・・・・  データロガー(その1)、電圧計: ADコンバーター、液晶表示器



  1. データロガーの作製:


  データロガーは、各種のセンサから電圧信号を受け取り、演算を加え、データを LCDで表示したり、CSV形式でパソコンへ送って処理しやすくする働きをする。 その入力側の基本形は、ADコンバーターを通しての 電圧計(0−5Vなど(電源電圧)を(8ビットでは)1024分割する)であり、これに 各種のセンサからの電圧信号を処理する機能を付け加えると、非常に応用範囲の広いシステムが出来上がる。
  出力側は、常時 結果を表示する 液晶表示器(LCD)や7セグLEDと共に、必要に応じて、パソコンにデータを送るための シリアル通信やUSB通信の機能を持たせる形となる。


  (1) 液晶表示2チャンネル電圧計の作製:


  @ PICの選定と接続回路図:

  PIC16F877Aは、ADコンバーターシリアル機能の両方を有し(cf. PIC12F675はシリアル無し、PIC16F628AはADコンバーター無し)、ピン数が多く(40pin)かさばる上、クロック生成器が不完全で水晶を必要とするが、汎用ポートが5組もあり、LCDのように多くのメモリを必要とするデータロガーにはふさわしいと思われる。(* ただし、シリアル通信は、シリアル出力端が無くてもプログラムで作ることができる。 温度計などの 機能が特化された専用器には、もっとコンパクトなPICを用いる。)

PIC12F675 PIC16F628A PIC16F877A
フラッシュメモリ(プログラムの保存)  1kワード  2kワード  8kワード
RAM(変数・バッファの割り当て)  64バイト  224バイト  368バイト
クロック生成器   内蔵   内蔵   不完全
タイマ0(標準8ビットタイマ)   内蔵   内蔵   内蔵
タイマ1(16ビットタイマ)   内蔵   内蔵   内蔵
タイマ2(周期設定可8ビット)   なし   内蔵   内蔵
CCPモジュール   なし   内蔵   内蔵
汎用ポート  1組6本  2組16本  5組33本
コンパレータ   1基   2基   1基
ADコンバータ  4チャンネル    なし  8チャンネル
シリアル   なし   内蔵   内蔵
同期式シリアル(SPI、I2C)   なし   なし   内蔵
PSP(ローカルバス送受信)   なし   なし   内蔵

  PIC16F877Aの ポートAをアナログ入力、ポートBをLCD駆動、ポートCをシリアル通信に割り当てた。(ポートD、Eは不使用) アナログ入力は AN0、AN1の2本(2チャンネルとなる)、LCD駆動は DB4〜7の4ビット・ドライブ、シリアルは TX(送信)、RX(受信)の2本だけとなる。 (* 配線は複雑そうに見えるが、ピンさえ間違えなければ比較的簡単にできる。 プリント基板(ナマ基板)へのICピッチの穴あけは、ユニバーサル基板を重ねてその上からφ.8ドリルで行なうと それほどずれない)



  A AD変換 と 簡単な演算:

  AD変換は、main関数の 各チャンネルごとに行なわれる。 チャンネル0では、ADCON0 の設定は、10000001 : 上位桁から 右寄せ、電源電圧、−、−、チャンネル0、チャンネル0、変換終了、電源スイッチON、のようになる。チャンネル1では、10001001 となる。
  * (追記) AD変換後のデータを取り出す記述を、 v=(ADRESH<<8)|ADRESL; から v=(ADRESH*256)+ADRESL; に変更します。前者は、PICのシフトレジスタの設計が悪くデータ取得ができないか不安定で、数値がふらつく原因となっている。
  ADコンバータの値は、電源電圧 5Vを 1024分割した値刻みの 0−1023 なので、5桁の作業領域を取ると、50000/1024 ≒ 49 をその値に掛けた数値、すなわち、変換結果 × 49 を計算し、小数点を2番目に入れ、○.○○○V の表示とする。(* 掛け算の最大値は、1023×49=50127 で、2バイトの変数領域 65535 以下なので、オーバーフロしない)
  小数点付きの計算はメモリを食うので、極力 整数型で計算する。

  B 液晶表示器の初期設定:

  LCDは、多くの場合、起動時、転送単位が 8ビット・モードになっているので、4ビットしか接続していない上記の回路では、4ビット・モードに設定し直す必要がある。
  LCDの ファンクションセットは、0,0,1,DL,N,F,0,0 で、 DL:転送単位(1: 8ビット、0: 4ビット)、N:表示行数(1: 2行、0: 1行)、F: フォントのドット構成(1: 5×10、0: 5×7) より、 0x03 = 0011 xxxx = 転送単位 8ビット、 0x28 = 0010 1000 = (4ビット、2行、5×7ドット) となる。
  OPTION で、プリスケーラーを 1/256 に設定(・ PIC16F628Aでは クロック4MHzなので 1/64)して、ファンクションセット時のそれぞれの必要な時間をつぶす。(20MHzの水晶発振子用であるが、10MHzにしても問題ない。) このように、LCDの起動時の不確定な動作を、3度も設定命令を出して確実に8ビットにしてから、改めて4ビットに切り替える必要がある。

  


  C 液晶表示プログラム:

  AD変換や演算によって与えられた数値データを、文字データに変換して 液晶やシリアル通信に送る必要がある。このための関数群(API)にまとめておくと便利である。

  液晶表示のAPIの一例として、
  下図の左側は、8ビットのデータを 上位4ビット・下位4ビットに分けて LCDに送るための基本関数群で、ビジー・フラグ(LCDからの唯一の入力)を確認して 同期信号を出し 書き込み可能になるのを待って命令とデータを書き込む。(* 随所に挿入されている NOP( ) はLCDが遅いことによる時間調整のためで、発振周波数4MHz以下では不要)

  右側は、main関数で用いられる出力用関数群で、
   ・ lcd_locate(x, y) : LCDの書き込み位置(カーソルの位置) ・・・・ ex) lcd_locate(0, 1) : 2行目の先頭、 lcd_locate(7, 1) : 2行目の8番目
   ・ lcd_putchr(d) : 1文字d(8ビット)を書き込む ・・・ lcd_putchr('d') : 1文字だけ
   ・ lcd_puts(*s) : 文字列を書き込む   ・・・ lcd_puts("abcde fgh") : 何文字でも良い(C言語文字列の最後は0)
   ・ lcd_putv(v) : 数値データを 文字列(4桁、小数点付き)に変換して書き込む

  


  また、次の ・ lcd_putui (ui, d)  ・・・ 数値 ui をd桁の10進数で表示、 ・ lcd_puthc(d)  ・・・ 16進数で表示、 ・ lcd_lclr( l ) ・・・ 指定行ごとに全クリヤ(LCD表示器は40文字×2行)、 も有用な関数で、そのまま、あるいは、小数点やブランクなどの一部の変更で用いることができる。

  

  ● ソース


 


                  戻る